﻿namespace PagedList
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;

    public abstract class BasePagedList<T> : PagedListMetaData, IPagedList<T>, IPagedList, IEnumerable<T>, IEnumerable
    {
        protected readonly List<T> Subset;

        protected internal BasePagedList(int index, int pageSize, int totalItemCount)
        {
            this.Subset = new List<T>();
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("index", index, "PageIndex cannot be below 0.");
            }
            if (pageSize < 1)
            {
                throw new ArgumentOutOfRangeException("pageSize", pageSize, "PageSize cannot be less than 1.");
            }
            base.TotalItemCount = totalItemCount;
            base.PageSize = pageSize;
            base.PageIndex = index;
            base.PageNumber = base.PageIndex + 1;
            base.PageCount = (base.TotalItemCount > 0) ? ((int) Math.Ceiling((double) (((double) base.TotalItemCount) / ((double) base.PageSize)))) : 0;
            base.HasPreviousPage = base.PageIndex > 0;
            base.HasNextPage = base.PageIndex < (base.PageCount - 1);
            base.IsFirstPage = base.PageIndex <= 0;
            base.IsLastPage = base.PageIndex >= (base.PageCount - 1);
            base.FirstItemOnPage = (base.PageIndex * base.PageSize) + 1;
            int num = (base.FirstItemOnPage + base.PageSize) - 1;
            base.LastItemOnPage = (num > base.TotalItemCount) ? base.TotalItemCount : num;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return this.Subset.GetEnumerator();
        }

        public IPagedList GetMetaData()
        {
            return new PagedListMetaData(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public int Count
        {
            get
            {
                return this.Subset.Count;
            }
        }

        public T this[int index]
        {
            get
            {
                return this.Subset[index];
            }
        }
    }
}

